#ifndef CICORE_VERTEX_H
#define CICORE_VERTEX_H

#include <cmath>
#include <vector>

#include "Matrix.h"
#include "Vector3D.h"
#include "Point.h"

namespace CICore {
    class Point;

    class Vertex {    

    public:        
        Vertex (const float x=0, const float y=0, const float z=0);          //Constructor
        Vertex (const Vertex& v);                                            //Contructor
        Vertex (const Point& p);                                             //Contructor
        virtual ~Vertex ();                                                  //Destructor

        float x, y, z;                              //Vertex's coordinates  

        Vector3D normal;                            //The vertex normal

        bool selected;                              //A boolean to indicates if the vertex is currently selected
        bool visible;                               //A boolean to indicates if the vertex is currently visible

        //Basic Point-to-Vertex conversion
        Vertex& operator = (Point& v);              //Basic Assignment        

        //CONSTANTS
        static const Vertex ORIGIN;

        //Utility Methods
        void Transform (const Matrix& m);

        static Vertex* MidPoint (const Vertex* v1, const Vertex* v2);
    };    

    typedef std::vector<Vertex*> VertexLib;        //Vertex Container
    typedef VertexLib::iterator VertexIter;        //Vertex Iterator
    
    //Basic vertex's unary operations
    Vertex& operator ++ (Vertex& v, int);                //Postfix increment
    Vertex& operator ++ (Vertex& v);                     //Prefix increment

    Vertex& operator -- (Vertex& v, int);                //Postfix decrement
    Vertex& operator -- (Vertex& v);                     //Prefix increment

    //Basic vertex's binary operations
    bool operator == (const Vertex& a, const Vertex& b);         //Equal to operator between two vertices

    Vertex operator + (const Vertex& a, const Vertex& b);        //Sum between two vertices
    Vertex& operator += (Vertex& a, const Vertex& b);            //Assignment by addition between two vertices

    Vertex operator - (const Vertex& a, const Vertex& b);        //Difference between two vertices
    Vertex& operator -= (Vertex& a, const Vertex& b);            //Assignment by substraction between two vertices
    
    Vertex operator * (const Vertex& a, const Vertex& b);        //Product between two vertices
    Vertex& operator *= (Vertex& a, const Vertex& b);            //Assignment by multiplication between two vertices
    
    Vertex operator / (const Vertex& a, const Vertex& b);        //Quotient between two vertices
    Vertex& operator /= (Vertex& a, const Vertex& b);            //Assignment by division between two vertices

    Vertex operator + (const Vertex& a, const float b);        //Sum between a vertex and a float value
    Vertex& operator += (Vertex& a, const float b);            //Assignment by addition between a vertex and a float value

    Vertex operator - (const Vertex& a, const float b);        //Difference between a vertex and a float value
    Vertex& operator -= (Vertex& a, const float b);            //Assignment by substraction between a vertex and a float value
    
    Vertex operator * (const Vertex& a, const float b);        //Product between a vertex and a float value
    Vertex& operator *= (Vertex& a, const float b);            //Assignment by multiplication between a vertex and a float value
    
    Vertex operator / (const Vertex& a, const float b);        //Quotient between a vertex and a float value
    Vertex& operator /= (Vertex& a, const float b);            //Assignment by division between a vertex and a float value


}
#endif /* CICORE_VERTEX_H */
